import json
from typing import Any

from tornado import httputil

import settings
import traceback

from db.redis.redis_service import RedisMemory
from common.log import logger

from db.es.es_service import ElasticsearchStorage
from bot.insurance_planner_gpt.interface.base_handler import BaseHandler, ReturnObj

es = ElasticsearchStorage()
redis_memory = RedisMemory()


class GetActiveSessionHandler(BaseHandler):

    def get(self):
        try:
            agent_client_id = self.get_argument('agent_client_id', '')
            sessionInfos = []
            active_connections = redis_memory.smembers("active_sessions:socket")
            if active_connections:
                sessionInfos = self.get_active_session_title(active_connections)
                for session in sessionInfos:
                    sessionId = session.get('sessionId', '')
                    session_takeover = redis_memory.get("agent_takeover:" + sessionId)
                    connect_client_ids = redis_memory.smembers("agent_connect:" + sessionId)
                    session['takeover'] = session_takeover
                    last_content = self.get_last_conversation_by_session_id(sessionId)
                    if last_content:
                        session['last_content'] = last_content
                    session['channel'] = "socket"
                    session['connect'] = 0
                    if connect_client_ids and agent_client_id in connect_client_ids:
                        session['connect'] = 1

            active_connections_qw = redis_memory.smembers("active_sessions:qw")
            if active_connections_qw:
                for active_session_id_qw in active_connections_qw:
                    sessionDict = {}
                    sessionDict["sessionId"] = active_session_id_qw
                    session_takeover = redis_memory.get("agent_takeover:" + active_session_id_qw)
                    connect_client_ids = redis_memory.smembers("agent_connect:" + active_session_id_qw)
                    sessionDict['takeover'] = session_takeover
                    sessionDict['title'] = "企微消息"
                    sessionDict['channel'] = "qw"
                    sessionDict['createTime'] = "1"
                    sessionDict['connect'] = 0
                    if connect_client_ids and agent_client_id in connect_client_ids:
                        sessionDict['connect'] = 1
                    last_content = self.get_last_conversation_by_session_id(active_session_id_qw)
                    if last_content:
                        sessionDict['last_content'] = last_content
                        sessionDict['createTime'] = last_content.get('message_time', "1")
                        sessionDict['createTime'] = sessionDict["createTime"].split('T')[1].split('.')[0]
                    else:
                        last_content = {"role": "user", "text_info": "新消息"}
                        sessionDict['last_content'] = last_content

                    sessionInfos.append(sessionDict)
            if agent_client_id:
                sessionInfos = sorted(sessionInfos,
                                      key=lambda session: (session['takeover'] != agent_client_id,
                                                           session['connect'], session['createTime']))
            return_obj = ReturnObj(200, 'success', sessionInfos)
            self.write(return_obj.to_json())
        except Exception as ee:
            logger.error(traceback.format_exc())
            return_obj = ReturnObj(500, 'success', traceback.format_exc())
            self.write(return_obj.to_json())

    def get_active_session_title(self, session_ids):
        sessionInfos = []
        try:

            query = {"query": {
                "bool": {
                    "must": [
                        {
                            "terms": {"session_id": list(session_ids)}
                        }
                    ]
                }
            }, "sort": [
                {
                    "message_time": {
                        "order": "desc"
                    }
                }
            ]
                , "size": 1000
            }
            results = es.search_documents(settings.USER_SESSION_INDEX, query)
            if results:
                for result in results:
                    sessionDict = {}
                    sessionDict["sessionId"] = result['_source']['session_id']
                    sessionDict["title"] = result['_source']['session_title']
                    sessionDict["createTime"] = result['_source']['message_time']
                    sessionDict["createTime"] = sessionDict["createTime"].split('T')[1].split('.')[0]
                    sessionInfos.append(sessionDict)
        except Exception as ee:
            pass
        finally:
            return sessionInfos

    def get_last_conversation_by_session_id(self, session_id):
        content = {}
        try:
            query = {
                "query": {
                    "bool": {
                        "must": [
                            {
                                "term": {
                                    "session_id": {
                                        "value": session_id
                                    }
                                }
                            }, {
                                "term": {
                                    "msg_type": {
                                        "value": "text"
                                    }
                                }

                            }
                        ]
                    }
                }, "sort": [
                    {
                        "message_time": {
                            "order": "desc"
                        }
                    }
                ]
                , "size": 1000
            }
            results = es.search_documents(settings.CONVERSATION_HISTORY_INDEX, query)
            if results:
                hit = results[0]
                role = hit["_source"]["role"]
                text_info = hit["_source"]["text_info"]
                msg_type = hit["_source"]["msg_type"]
                message_time = hit["_source"]["message_time"]
                content["role"] = role
                content["text_info"] = text_info
                content["message_time"] = message_time
            return content
        except Exception as ee:
            logger.error(traceback.format_exc())
            return content


class GetSessionTakeoverStatusHandler(BaseHandler):

    def get(self):
        try:
            sessionId = self.get_argument('sessionId', '')
            session_takeover = redis_memory.get("agent_takeover:" + sessionId)
            return_obj = ReturnObj(200, 'success', session_takeover)
            self.write(return_obj.to_json())
        except Exception as ee:
            logger.error(traceback.format_exc())
            return_obj = ReturnObj(500, 'success', traceback.format_exc())
            self.write(return_obj.to_json())


class AgentLogOutHandler(BaseHandler):

    def get(self):
        try:
            username = self.get_argument('username', '')

            # 清除所有坐席链接
            redis_memory.find_and_remove_value(key_prefix="agent_connect", value_to_remove=username)

            keys_to_delete = redis_memory.keys('agent_takeover:*')
            for key in keys_to_delete:
                if redis_memory.get(key) == username:
                    redis_memory.delete(key)
            session_takeover = redis_memory.get("agent_takeover:" + username)
            return_obj = ReturnObj(200, 'success', session_takeover)
            self.write(return_obj.to_json())
        except Exception as ee:
            logger.error(traceback.format_exc())
            return_obj = ReturnObj(500, 'success', traceback.format_exc())
            self.write(return_obj.to_json())
